package lar.game.gamestate;

import java.io.IOException;

import javax.microedition.khronos.opengles.GL11;

import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.util.Log;
import android.view.MotionEvent;
import lar.game.physics.Rotation;
import lar.game.physics.Vector;
import lar.system.R;
import lar.system.engine.MainProgram;
import lar.system.engine.TouchListener;
import lar.system.network.BluetoothConnection;
import lar.system.opengl.GLButton;
import lar.system.opengl.GLColor;
import lar.system.opengl.GLImage;
import lar.system.opengl.GLRButton;
import lar.system.opengl.GLString;
import lar.system.sound.Sound;

public class FunMenu implements GameState 
{
	private BluetoothConnection connection;
	
	private int seq = 0;
	private float wheelAngle = 0;
	private float lastRotation = 0;
	float delta_angle=0;
	int init_angle = 0;
	float handleValue = -1;
	int delta_force=0;
	private GLButton odedWheel;
	private GLImage powerScale;
	private GLButton powerSlide;
	private GLString angleStr, thrustStr;
	private float prev_force = 0;
	private float force = 0;
	
	boolean reverse = false;
	private GLRButton gearButton;
	
	private GLRButton disconnectButton;
	
	public FunMenu(BluetoothConnection connection)
	{
		this.connection = connection;
		float asp = MainProgram.glSurfaceView.getAspectRatio();
		disconnectButton = new GLRButton(new float[]{-asp+0.4f, 0.9f}, new float[]{0.4f, 0.1f}, "Disconnect", 0.06f, GLColor.RED, new GLRButton.RButtonListener() 
		{
			public void event() 
			{
				Disconnect();
			}
		});
		disconnectButton.setImages(R.drawable.button2, R.drawable.button2pressed);
		odedWheel = new GLButton(R.drawable.horeshwheel, new float[]{asp-0.7f, -0.4f}, new float[]{0.6f, 0.6f}, new OdedWheel(new float[]{asp-0.7f, -0.4f}));
		//odedWheel.getImage().setMaskColor(new GLColor(1,1,1,0.4f));
		powerSlide = new GLButton(R.drawable.powerhandle, new float[]{-asp+0.3f, getPowerSlidePos()}, new float[]{0.24f, 0.6f}, new PowerHandle());
		//powerSlide.getImage().setMaskColor(new GLColor(1,1,1,0.4f));
		powerScale = new GLImage(R.drawable.powerscale, new float[]{-asp+0.3f, -0.1f}, new float[]{0.3f,0.8f});
		//powerScale.setMaskColor(new GLColor(1,1,1,0.4f));
		
		angleStr = new GLString(R.drawable.basefont, "Angle: " + wheelAngle, new float[]{0, 0.7f}, 0.07f);
		thrustStr = new GLString(R.drawable.basefont, "Thrust: " + force, new float[]{0, 0.55f}, 0.07f);
		angleStr.setColor(GLColor.YELLOW.asFloatArray());
		thrustStr.setColor(GLColor.DARKGREEN.asFloatArray());
		gearButton = new GLRButton(new float[]{-asp+1.1f, -0.85f}, new float[]{0.4f, 0.1f}, "Reverse", 0.06f, GLColor.LIME, new GLRButton.RButtonListener() 
		{
			public void event() 
			{
				reverse = !reverse;
				if(reverse) gearButton.setString("Forward");
				else gearButton.setString("Reverse");
				
				changePower(-1000);
				
			}
		});
	}
	
	public float getPowerSlidePos()
	{
		//float force = (float) game.GetCurrentPlayer().GetTank().GetForce();
		float max_y = 0.6f;
		float min_y = -0.8f;
		return min_y + (force/1000)*(max_y-min_y);
	}
	
	public boolean CheckBounds(float gl_x, float gl_y) 
	{
		return false;
	}

	private void Disconnect()
	{
		connection.close();
		connection = null;
		MainProgram.MessageBoxStrict("Disconnected.", new OnClickListener() 
		{
			public void onClick(DialogInterface dialog, int which) 
			{
				MainProgram.glSurfaceView.ClearListeners();
				MainProgram.gameLoop.ChangeState(new MainMenu());
			}
		});
		
	}
	@Override
	public void gameFrame() 
	{
		if(connection == null) return;
		seq++;
		if(seq % 10 == 0)
		{
			int speed = (int)(force / 11);
			if(reverse) speed *= -1;
			int dir = (int)wheelAngle;
			String speedstr = ""+speed;
			if(speedstr.length() == 1) speedstr = "0" + speedstr;
			if(speed >= 0) speedstr = "+" + speedstr;
			
			String dirstr = "" + dir;
			if(dirstr.length() == 1) dirstr = "0" + dirstr;
			if(dir >= 0) dirstr = "+" + dirstr;
			connection.write("$" + speedstr + "" + dirstr + "xxxxxx");
		}
		if(connection.hasIncomingMsgs())
		{
			String msg = connection.getIncomingMessage();
			Log.d("R", "got: " + msg);
		}
		
		/*
		if(connection != null)
		{
			//Log.d("R", "frame2");
			if(connection.hasIncomingMsgs())
			{
				//Log.d("R", "frame3");
				String msg = connection.getIncomingMessage();
				MainProgram.MessageBox("Incoming: " + msg);
			}
			//Log.d("R", "frame4");
			
		}
		*/
	}

	@Override
	public void Draw(GL11 gl) 
	{
		odedWheel.Draw(gl);
		disconnectButton.Draw(gl);
		powerScale.Draw(gl);
		powerSlide.Draw(gl);
		angleStr.Draw(gl);
		thrustStr.Draw(gl);
		gearButton.Draw(gl);
	}

	@Override
	public void onPause() 
	{
		
	}

	@Override
	public void onResume() 
	{
		
	}

	@Override
	public void onDestroy() {
		Disconnect();
		
	}

	@Override
	public void onBack() {
		Disconnect();
		
	}

	
	public void angleWheelMove(double d_rot)
	{
		
		wheelAngle -= d_rot/2;
		double playerRotation = lastRotation;
		double finalRot = playerRotation+d_rot/10;
		if(finalRot < 0) finalRot = 0;
		if(finalRot > 180) finalRot = 180;
		lastRotation = (float)finalRot;
		//if((int)delta_angle-(int)((int)(finalRot)-init_angle) != 0) Sound.playSound(R.raw.button_hard);
		delta_angle = (int)finalRot-init_angle;
		if(wheelAngle > 99) wheelAngle = 99;
		else if(wheelAngle < -99) wheelAngle = -99;
		else
		{
			angleStr.SetString("Angle: " + wheelAngle);
			odedWheel.getImage().setRotation(wheelAngle);
		}
	}
	
	class OdedWheel implements TouchListener
	{
		private double last_rot;
		private float[] glPos;
		
		public OdedWheel(float[] glPos)
		{
			this.glPos = glPos;
		}
		public void onTouchEvent(MotionEvent e) 
		{
			FunMenu stage = (FunMenu) MainProgram.gameLoop.getState();
			
			if(e.getAction() == MotionEvent.ACTION_DOWN)
			{	
				MainProgram.glSurfaceView.lockUI(this);
				
				float new_y = e.getY();
				float new_x = e.getX();
				
				float asp = MainProgram.glSurfaceView.getAspectRatio();
				float center_x = glPos[0];
				float center_y = glPos[1];
				center_x = MainProgram.glSurfaceView.getWidth()*(center_x + asp)/(2*asp);
				center_y = MainProgram.glSurfaceView.getHeight()*(1-(center_y + 1)/2);
				
				Vector v = new Vector( new_x-center_x, center_y-new_y);
				Rotation r = new Rotation(v);
				last_rot = r.AsDegrees();
				
				
			}
			else if(e.getAction() == MotionEvent.ACTION_MOVE)
			{
				float new_y = e.getY();
				float new_x = e.getX();
				
				float asp = MainProgram.glSurfaceView.getAspectRatio();
				float center_x = glPos[0];
				float center_y = glPos[1];
				center_x = MainProgram.glSurfaceView.getWidth()*(center_x + asp)/(2*asp);
				center_y = MainProgram.glSurfaceView.getHeight()*(1-(center_y + 1)/2);
				
				Vector v = new Vector( new_x-center_x, center_y-new_y);
				Rotation r = new Rotation(v);
				double rot = r.AsDegrees();
				double d_rot = rot - last_rot;
				if(d_rot > 180) d_rot -= 360;
				else if(d_rot < -180) d_rot += 360;
				//Log.d("R", ""+d_rot);
				last_rot = rot;
				stage.angleWheelMove(d_rot);
				//stage.contactHoreshWheel(true);
				
			}
			else if(e.getAction() == MotionEvent.ACTION_UP)
			{
				MainProgram.glSurfaceView.lockUI(null);
				//stage.contactHoreshWheel(false);
			
			}	
		}
	}
	
	public void changePower(float value)
	{
		float max_y = 0.6f;
		float min_y = -0.8f;
		if(handleValue == -1) handleValue = getPowerSlidePos();
		handleValue += value;
		float[] coords = powerScale.getGLPos();
		float asp = MainProgram.glSurfaceView.getAspectRatio();
		if(handleValue > max_y) handleValue = max_y;
		if(handleValue < min_y) handleValue = min_y;
		coords[1] = handleValue;
		coords[0] = coords[0];
		force = (handleValue-min_y)/(max_y-min_y)*1000;
		//int prev_force = game.GetCurrentPlayer().GetTank().GetForce();
		//game.GetCurrentPlayer().GetTank().SetForce(Math.round(force));
		delta_force += force-prev_force;
		//updateHUDs();
		//if(Math.round(force) - prev_force != 0) Sound.playSound(R.raw.button_soft);
		powerSlide.getImage().setGLCoords(coords);
		//currentTurnVal = 0;
		thrustStr.SetString("Thrust: " + (reverse ? "-" : "") + force);
		
	}
	
	class PowerHandle implements TouchListener
	{
		private float h = MainProgram.glSurfaceView.getHeight();
		private float last_y;
		public void onTouchEvent(MotionEvent e) 
		{
			FunMenu stage = (FunMenu) MainProgram.gameLoop.getState();
			if(e.getAction() == MotionEvent.ACTION_DOWN)
			{
				last_y = e.getY();
				MainProgram.glSurfaceView.lockUI(this);
			}
			if(e.getAction() == MotionEvent.ACTION_MOVE)
			{
				float new_y = e.getY();
				float dy = new_y-last_y;
				if(dy == 0) return;
				//x^2 / (1+x)
				//Log.d("R", "B " + dy);
				dy = Math.signum(dy)*(3*dy*dy)/(Math.abs(dy)+25);
				//Log.d("R", "A " + dy);
				stage.changePower(-dy/(0.5f*h));
				last_y = new_y;
				//stage.contactPowerHandle(true);
			}
			else if(e.getAction() == MotionEvent.ACTION_UP)
			{
				//stage.contactPowerHandle(false);
				MainProgram.glSurfaceView.lockUI(null);
			}
		}
	}
}
